<template>
  <div class="base-table-container">
    <!-- 表格主体 -->
    <el-table
      :data="paginatedData"
      :border="border"
      :header-row-style="headerRowStyle"
      :header-cell-style="headerCellStyle"
      :row-style="rowStyle"
      :cell-style="cellStyle"
      :empty-text="emptyText"
      @sort-change="handleSortChange"
      ref="tableRef"
    >
      <!-- 多选列（可选） -->
      <el-table-column
        v-if="showSelection"
        type="selection"
        width="55"
        align="center"
      />

      <!-- 序号列（可选） -->
      <el-table-column
        v-if="showIndex"
        type="index"
        width="60"
        label="序号"
        :index="indexMethod"
        align="center"
      />

      <!-- 动态列渲染 -->
      <el-table-column
        v-for="(col, idx) in columns"
        :key="idx"
        :label="col.label"
        :width="col.width"
        :min-width="col.minWidth"
        :align="col.align || 'left'"
        :sortable="col.sortable"
      >
        <template #default="scope">
          <!-- 行内编辑逻辑：根据列配置和行编辑状态决定显示内容 -->
          <div v-if="col.editable && scope.row._editMode" class="editable-cell">
            <!-- 输入框 -->
            <el-input
              v-if="col.editType === 'input'"
              v-model="scope.row[col.prop]"
              :placeholder="col.placeholder || '请输入'"
              @blur="exitEditMode(scope.row)"
              :style="{ width: col.editWidth || '100%' }"
              :autofocus="true"
            />

            <!-- 下拉选择器 -->
            <el-select
              v-else-if="col.editType === 'select'"
              v-model="scope.row[col.prop]"
              :placeholder="col.placeholder || '请选择'"
              @change="exitEditMode(scope.row)"
              :style="{ width: col.editWidth || '100%' }"
            >
              <el-option
                v-for="opt in col.options || []"
                :key="opt.value"
                :label="opt.label"
                :value="opt.value"
              />
            </el-select>

            <!-- 日期选择器 -->
            <el-date-picker
              v-else-if="col.editType === 'date'"
              v-model="scope.row[col.prop]"
              type="date"
              :placeholder="col.placeholder || '请选择日期'"
              @change="exitEditMode(scope.row)"
              :style="{ width: col.editWidth || '100%' }"
            />
          </div>

          <!-- 非编辑状态显示 -->
          <div
            v-else
            class="normal-cell"
            @dblclick="enterEditMode(scope.row, col)"
          >
            <slot
              v-if="col.slot"
              :name="col.slot"
              :row="scope.row"
              :column="col"
            >
              {{ formatCell(scope.row[col.prop], col.formatter) }}
            </slot>
            <template v-else>
              {{ formatCell(scope.row[col.prop], col.formatter) }}
            </template>
          </div>
        </template>
      </el-table-column>

      <!-- 操作列（可选） -->
      <el-table-column
        v-if="showAction"
        label="操作"
        align="center"
        :width="actionWidth"
      >
        <template #default="scope">
          <slot name="action" :row="scope.row">
            <el-button
              v-if="editable"
              type="text"
              @click="enterEditMode(scope.row)"
              icon="el-icon-edit"
              >编辑</el-button
            >
            <el-button
              v-if="editable"
              type="text"
              @click="handleDelete(scope.row)"
              icon="el-icon-delete"
              >删除</el-button
            >
          </slot>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页组件 -->
    <el-pagination
      class="pagination"
      :current-page="pagination.currentPage"
      :page-size="pagination.pageSize"
      :page-sizes="pagination.pageSizes"
      :total="total"
      layout="total, sizes, prev, pager, next, jumper"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
      background
    />
  </div>
</template>

<script setup>
import { ref, reactive, computed, onMounted, watch } from "vue";

// 接收父组件参数
const props = defineProps({
  total: {
    type: Number,
    default: 0,
  },
  // 表格数据
  tableData: {
    type: Array,
    default: () => [],
  },
  // 列配置
  columns: {
    type: Array,
    required: true,
    default: () => [],
  },
  // 分页配置
  pagination: {
    type: Object,
    default: () => ({
      currentPage: 1, // 当前页
      pageSize: 10, // 每页条数
      pageSizes: [10, 20, 50, 100], // 每页条数选项
    }),
  },
  // 是否显示多选框
  showSelection: {
    type: Boolean,
    default: false,
  },
  // 是否显示序号列
  showIndex: {
    type: Boolean,
    default: false,
  },
  // 是否显示操作列
  showAction: {
    type: Boolean,
    default: false,
  },
  // 操作列宽度
  actionWidth: {
    type: String,
    default: "180",
  },
  // 是否可编辑
  editable: {
    type: Boolean,
    default: false,
  },
  // 空数据提示
  emptyText: {
    type: String,
    default: "暂无数据",
  },
  // 表头行样式
  headerRowStyle: {
    type: Object,
    default: () => ({}),
  },
  // 表头单元格样式
  headerCellStyle: {
    type: Object,
    default: () => ({}),
  },
  // 行样式
  rowStyle: {
    type: Object,
    default: () => ({}),
  },
  // 单元格样式
  cellStyle: {
    type: Object,
    default: () => ({}),
  },
});

watch(
  () => props.pagination.total,
  (val) => {
    props.total = val;
  }
);

// 向父组件触发事件
const emit = defineEmits([
  "sort-change", // 排序变化
  "page-change", // 分页变化
  "edit", // 编辑事件
  "delete", // 删除事件
  "selection-change", // 多选变化
]);

// 表格引用
const tableRef = ref();

// 响应式分页数据
const pagination = reactive({ ...props.pagination });

// 分页后的数据
const paginatedData = computed(() => {
  const start = (pagination.currentPage - 1) * pagination.pageSize;
  const end = start + pagination.pageSize;
  return props.tableData.slice(start, end);
});

// 处理表头排序
const handleSortChange = ({ prop, order }) => {
  emit("sort-change", { prop, order });
};

// 处理每页条数变化
const handleSizeChange = (pageSize) => {
  pagination.pageSize = pageSize;
  pagination.currentPage = 1;
  emit("page-change", pagination);
};

// 处理页码变化
const handleCurrentChange = (currentPage) => {
  pagination.currentPage = currentPage;
  emit("page-change", pagination);
};

// 处理删除事件
const handleDelete = (row) => {
  emit("delete", row);
};

// 进入编辑模式
const enterEditMode = (row, column) => {
  // 关闭其他行的编辑模式
  props.tableData.forEach((item) => {
    if (item !== row) {
      item._editMode = false;
    }
  });
  // 开启当前行的编辑模式
  row._editMode = true;
  emit("edit", { row, column, status: "enter" });
};

// 退出编辑模式
const exitEditMode = (row) => {
  row._editMode = false;
  emit("edit", { row, status: "exit" });
};

// 格式化单元格内容（支持自定义 formatter）
const formatCell = (value, formatter) => {
  if (typeof formatter === "function") {
    return formatter(value);
  }
  return value;
};

// 序号生成方法（支持分页）
const indexMethod = (index) => {
  return (pagination.currentPage - 1) * pagination.pageSize + index + 1;
};

// 暴露方法给父组件
defineExpose({
  // 清除所有排序
  clearSort: () => tableRef.value.clearSort(),
  // 清除所有选择
  clearSelection: () => tableRef.value.clearSelection(),
  // 获取选中行
  getSelectionRows: () => tableRef.value.getSelectionRows(),
});
</script>

<style scoped lang="less">
.base-table-container {
  display: flex;
  flex-direction: column;
  background: #fff;
  padding: 20px;
}

.pagination {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
}

.normal-cell {
  min-height: 24px;
  cursor: pointer;
}

.editable-cell {
  padding: 0;
}
:deep(.el-pagination) {
  margin-top: 20px;
  display: flex;
  justify-content: flex-end;
  --el-pagination-button-bg-color: #fff;
  --el-disabled-bg-color: rgba(245, 247, 250, 1);
  padding: 0 20px 10px 0;
  .btn-prev,
  .btn-next {
    background-color: var(--el-disabled-bg-color);
  }
  .btn-prev:disabled,
  .btn-next:disabled {
    background-color: var(--el-disabled-bg-color);
  }
  .el-pager {
    li {
      border: 1px solid #eee;
    }
  }
}
:deep(.el-table) {
  th.el-table__cell {
    background-color: #f2f6fd;
  }
  thead {
    color: var(--el-table-header-text-color);
  }
  .el-table__cell {
    padding: 0;
    height: 46px;
    line-height: 46px;
  }
  th.el-table__cell {
    border-right: 1px solid #ebeef5;
  }
}
</style>